package abac

import (
	"fmt"
	"strings"
)

// 节点（字典树）
type MyNode struct {
	// Data
	children map[interface{}]*MyNode //子节点
	isEnd    bool
}

// 二叉树
type MyTree struct {
	Root *MyNode
}

// 构造访问策略树
func NewTree() *MyTree {
	return &MyTree{Root: NewTreeNode()}
}

// 构造树节点
func NewTreeNode() *MyNode {
	return &MyNode{
		// Data:  data,
		children: make(map[interface{}]*MyNode),
		isEnd:    false,
	}
}

// 向访问策略树插入一个访问策略
func (mt *MyTree) Append(policy []interface{}) {
	node := mt.Root
	for i := 0; i < len(policy); i++ {
		_, ok := node.children[policy[i]]
		// 如果该节点不存在，则构造一个节点
		if !ok {
			node.children[policy[i]] = NewTreeNode()
		}
		node = node.children[policy[i]]
	}
	node.isEnd = true
}

// 搜索树中是否存在指定单词
func (mt *MyTree) Search(policy []interface{}) bool {
	node := mt.Root
	for _, j := range policy {
		_, ok := node.children[j]
		// fmt.Println("ok", j, len(policy), i)
		// fmt.Println(ok, j, len(policy), i, node.children)

		if !ok {
			return false
		}
		node = node.children[j]
	}
	return node.isEnd
}

// 判断树中是否有指定前缀的单词
func (mt *MyTree) StartsWith(prefix []interface{}) bool {
	node := mt.Root
	for i := 0; i < len(prefix); i++ {
		_, ok := node.children[prefix[i]]
		if !ok {
			return false
		}
		node = node.children[prefix[i]]
	}
	return true
}

// 把policy变成tree存储
func PolicyToTree(policy *Policy) *MyTree {
	// var alltree []*MyTree
	tree := NewTree()
	m := 0
	// oldi:=0
	// f := 0
	// for i, j := range policy.SubRules {
	for i := 0; i < len(policy.SubRules); i++ {
		// if f {
		// 	i = i - 1
		// }
		rule := policy.SubRules[i]
		var value []interface{}
		// fmt.Println(reflect.TypeOf(rule))

		// values := dataProcess(rule)
		values := strings.Split(rule, ",")
		fmt.Println("-----第", i, "条values is ", values)
		for k, v := range values {
			fmt.Println("第", k, "个v is ", v)
			// fmt.Println(v)
			res1 := strings.Contains(v, "action")
			if res1 {
				if v == "action:all" || v == "action:rwd" {
					v = "action:r&w&d"
				} else if v == "action:rw" {
					v = "action:r&w"
				} else if v == "action:rd" {
					v = "action:r&d"
				} else if v == "action:wd" {
					v = "action:w&d"
				}
				action := strings.Split(strings.Split(v, ":")[1], "&")[m]
				// fmt.Println(action)
				// newvalues := ""
				// for _, a := range actions {
				newvalues := "action:" + action
				value = append(value, newvalues)
				if m < len(strings.Split(strings.Split(v, ":")[1], "&"))-1 {
					m += 1
					i -= 1
					fmt.Println(m, i, len(strings.Split(strings.Split(v, ":")[1], "&")))
				} else {
					m = 0
				}
			} else {
				value = append(value, v)
			}
			// fmt.Println("k is ", k, "个v", value)
		}
		// fmt.Println("-----第", i, "条value is ", value, "---")

		tree.Append(value)
	}
	return tree
}

func PreorderPrint(mn *MyNode) {
	if mn == nil {
		return
	}
	// fmt.Print(len(mn.children), " ")
	// fmt.Print(mn.children, " ")
	for _, child := range mn.children {
		fmt.Print(child, "->")
		// fmt.Println("child is ", child, " ")
		// fmt.Println(mn.children[child], " ")
		PreorderPrint(mn.children[child])
	}
	fmt.Println("\n=====")
}
